﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Linq;
using System.Configuration;
using System.Web.Mvc;

namespace Pulog.Models
{
    public partial class PostRepository : IPostRepository
    {
        private readonly PulogDataContext dc = new PulogDataContext();

        public Post GetPostBySlug(string slug)
        {
            return dc.Posts.SingleOrDefault<Post>(p => p.slug == slug);
        }

        public Post GetPostById(int id)
        {
            Post post = dc.Posts.SingleOrDefault(p => p.postID == id);
            // convert the html after the save of view++ to avoid changing the orinal html content
            post.content = Helper.TranslateOldBlogUBB(post.content);
            return post;
        }

        public PagedList<Post> GetPostList(int? pageIndex)
        {
            //DataLoadOptions options = new DataLoadOptions();
            //options.LoadWith<Post>(p => p.PostTags);
            //options.LoadWith<PostTag>(pc => pc.Tag);
            //dc.LoadOptions = options;
            int pIndex = pageIndex ?? 1;
            PagedList<Post> result = dc.Posts.OrderByDescending(p => p.pubTime).ToPagedList<Post>(pIndex);
            //return dc.Posts.Skip(Helper.PageSize * (pIndex - 1)).Take(Helper.PageSize).OrderByDescending(p => p.pubTime).ToPagedList<Post>(pIndex);
            foreach (Post p in result)
            {
                p.content = Helper.TranslateOldBlogUBB(p.content);
            }
            List<Post> stickyPosts = (from p in dc.Posts
                                      where p.sticky == 1
                                      select p).ToList();
            if (stickyPosts.Count != 0 && pageIndex == null)
            {
                foreach(Post p in stickyPosts)
                {
                    result.Remove(p);
                }
                result.InsertRange(0, stickyPosts);
            }
            return result;

            //return dc.Posts.ToList();
        }

        public List<Post> GetPostsByNumbers(int numberOfPosts)
        {
            List<Post> result = dc.Posts.OrderByDescending(p => p.pubTime).Take(numberOfPosts).ToList();
            foreach (Post p in result)
            {
                p.content = Helper.TranslateOldBlogUBB(p.content);
            }
            return result;
        }

        public void InsertPost(Post post)
        {
            //Post p = new Post()
            //{
            //    authorID = post.authorID,
            //    categoryID = post.categoryID,
            //    // no comments for new post
            //    content = post.content,
            //    password = post.password,
            //    // no postID
            //    property = post.property,
            //    pubTime = DateTime.Now,
            //    slug = post.slug,
            //    sticky = post.sticky,
            //    title = post.title,
            //    views = 0
            //};
            dc.Posts.InsertOnSubmit(post);
        }

        public void DeletePost(Post post)
        {
            dc.Comments.DeleteAllOnSubmit(post.Comments);
            dc.Posts.DeleteOnSubmit(post);
        }

        public Comment GetCommentByID(int id)
        {
            return dc.Comments.Single(c => c.CommentID == id);
        }

        public void AddComment(Comment comment)
        {
            dc.Comments.InsertOnSubmit(comment);
        }

        public void DeleteComment(Comment comment)
        {
            dc.Comments.DeleteAllOnSubmit(comment.Comments);
            dc.Comments.DeleteOnSubmit(comment);
        }

        public List<Post> GetPostsByCategoryName(string name)
        {
            return dc.Posts.Where(p => p.Category.categoryName == name).OrderByDescending(p => p.pubTime).ToList();
        }

        //public List<Post> GetPostsByTagName(string tag)
        //{
        //    return dc.Posts.Where(s => s.PostTags.Single(pt => pt.Tag.TagName.ToLower() == tag.Trim().ToLower()) != null).ToList();
        //}

        public PagedList<Comment> GetRecentComments()
        {
            //return dc.Comments.OrderByDescending(c => c.CommentTime).Take(10).ToList();
            return dc.Comments.OrderByDescending(c => c.CommentTime).Take(10).ToPagedList<Comment>(1);
        }

        public List<Category> GetCategories()
        {
            return dc.Categories.OrderBy(c=>c.categoryOrder).ToList();
        }

        public PagedList<Post> GetRecentPostList()
        {
            // Get the first page of all posts, the number of posts in the page is defined in Settings table
            return GetPostList(1);
        }

        public PagedList<Post> SearchPosts(string searchTerm, string searchMode, int? pageIndex)
        {
            int page = pageIndex ?? 1;
            if (string.IsNullOrEmpty(searchMode))
            {
                searchMode = "TitlesOnly";
            }
            if (searchMode.Equals("TitlesOnly",StringComparison.OrdinalIgnoreCase))
            {
                var query = from p in dc.Posts
                            where p.title.Contains(searchTerm)
                            orderby p.pubTime
                            select p;
                return query.ToPagedList(page);
            }
     
            else if(searchMode.Equals("FullText", StringComparison.OrdinalIgnoreCase))
            {
                var query = from p in dc.Posts
                            where p.title.Contains(searchTerm) || p.content.Contains(searchTerm)
                            orderby p.pubTime
                            select p;
                return query.ToPagedList(page);
            }
            return null;
        }

        // Persistence 
        public void Save()
        {
            dc.SubmitChanges();
        }

        // Miscs
        public int CheckSlug(string slug)
        {
            return (from p in dc.Posts
                    where p.slug == slug
                    select p).Count();

        }

        //public List<Tag> GetAllTags()
        //{
        //    return dc.Tags.ToList();
        //}

        //public List<int> AddTags(string[] tags)
        //{
        //    List<int> tagIDList = new List<int>();

        //    foreach (string tagName in tags)
        //    {
        //        Tag t = dc.Tags.SingleOrDefault(c => c.TagName.ToLower() == tagName.Trim().ToLower());
        //        if (t == null)
        //        {
        //            t = new Tag()//tag does not exist in db
        //            {
        //                TagName = tagName.Trim(),
        //            };
        //            dc.Tags.InsertOnSubmit(t);
        //            Save();
        //        }
        //        tagIDList.Add(t.TagID);
        //    }

        //    return tagIDList;
        //}

        //public List<int> EditPostWithTags(int postID, string[] tags)
        //{
        //    List<int> tagsIDList = AddTags(tags);
        //    // selects the tags have been removed from the post
        //    List<int> toDelete = (from t in dc.PostTags
        //            where t.PostID == postID && !(tagsIDList.Contains(t.TagID))
        //             select t.PostTagID).ToList();
            
        //    foreach(int postTagID in toDelete)
        //    {
        //        dc.PostTags.DeleteOnSubmit(dc.PostTags.Single(pt=>pt.PostTagID==postTagID));
        //    }
            
        //    //selects the tags have been newly added to the post
        //    List<int> currentPostTagIDList = (from pt in dc.PostTags
        //                                      where pt.PostID == postID
        //                                      select pt.TagID).ToList();
        //    List<int> toAdd = (from t in tagsIDList
        //                       where !(currentPostTagIDList.Contains(t))
        //                       select t).ToList();
        //    foreach (int tagID in toAdd)
        //    {
        //        PostTag postTag = new PostTag(){ PostID=postID, TagID=tagID };
        //        dc.PostTags.InsertOnSubmit(postTag);
        //    }

        //    Save();
        //    return toDelete;

        //}

        //public void DeleteTags(Tag tag)
        //{
        //    dc.PostTags.DeleteAllOnSubmit(tag.PostTags);
        //    dc.Tags.DeleteOnSubmit(tag);
        //}

        //public void RemoveTagsFromPost(Post post)
        //{
        //    dc.PostTags.DeleteAllOnSubmit(post.PostTags);
        //}

        //public Tag GetTagByID(int id)
        //{
        //    return dc.Tags.Single(t => t.TagID == id);
        //}

        public string GetAttachmentOriginalNameByID(int id)
        {
            return dc.Attachments.Single(a => a.attachmentID == id).originalName;
        }
    }

    public partial class Post
    {
        private readonly PulogDataContext dc = new PulogDataContext();

        private string _tags;
        partial void OnTagsChanging(string value);
        partial void OnTagsChanged();

        //public string Tags
        //{
        //    get
        //    {
        //        if (_tags == null)
        //        {
        //            string s = "";
        //            foreach (PostTag pt in PostTags)
        //            {
        //                s += pt.Tag.TagName + ',';
        //            }
        //            if (!string.IsNullOrEmpty(s))
        //            {
        //                _tags = s.Substring(0, s.Length - 1);
        //            }
        //            else _tags = null;
        //            return _tags;
        //        //return dc.Tags.ToList<Tag>().ToString();
        //        }
        //        else
        //        {
        //            return _tags;
        //        }
        //    }
        //    set
        //    {
        //        if ((this._tags != value))
        //        {
        //            this.OnTagsChanging(value);
        //            this.SendPropertyChanging();
        //            this._tags = value;
        //            this.SendPropertyChanged("Tags");
        //            this.OnTagsChanged();
        //        }
        //    }
        //}
        public IEnumerable<DropDown> DropDownProperties
        {
            get
            {
                return new List<DropDown>() { 
                    new DropDown() {TextField = "Published", ValueField = 0},
                    new DropDown() {TextField = "Locked", ValueField = 1},
                    new DropDown() {TextField = "Hidden", ValueField = 2 }
                };
            }
        }
        public IEnumerable<DropDown> DropDownCategories
        {
            get
            {
                List<Category> categories = new CategoryRepository().GetAllCategories();
                List<DropDown> result = new List<DropDown>();
                foreach (Category c in categories)
                {
                    result.Add(new DropDown() { TextField = c.categoryName, ValueField = c.categoryID });
                }
                return result;
            }
        }
        public IEnumerable<DropDown> DropDownSticky
        {
            get
            {
                return new List<DropDown>() { 
                    new DropDown() {TextField = "Yes", ValueField=1},
                    new DropDown() {TextField = "No", ValueField = 0},
                };
            }
        }
    }
}